<template>
    <div v-loading="loading" :element-loading-delay="sslList?.length > 0 ? 120 : 0" class="console-page ssl">
        <el-row class="toolbar">
            <el-col :span="20">
                <div class="total-desc forbid-select">
                    <span :class="getFilterButtonClass('total')" @click="setFilter('total')" v-if="sslSummary.total">
                        <span>总计：</span><span>{{ sslSummary.total }}</span>
                    </span>
                    <span :class="getFilterButtonClass('review')" @click="setFilter('review')" v-if="sslSummary.review">
                        <span>申请中：</span><span>{{ sslSummary.review }}</span>
                    </span>
                    <span :class="getFilterButtonClass('isExpiring')" @click="setFilter('isExpiring')"
                          v-if="sslSummary.isExpiring">
                        <span>即将过期：</span><span>{{ sslSummary.isExpiring }}</span>
                    </span>
                    <span :class="getFilterButtonClass('expired')" @click="setFilter('expired')"
                          v-if="sslSummary.expired">
                        <span>已过期</span><span>{{ sslSummary.expired }}</span>
                    </span>
                    <span :class="getFilterButtonClass('sign')" @click="setFilter('sign')" v-if="sslSummary.sign">
                        <span>已颁发：</span><span>{{ sslSummary.sign }}</span>
                    </span>
                    <span :class="getFilterButtonClass('revoked')" @click="setFilter('revoked')"
                          v-if="sslSummary.revoked">
                        <span>已吊销：</span><span>{{ sslSummary.revoked }}</span>
                    </span>
                </div>
            </el-col>
            <el-col :span="4" style="text-align:right">
                <el-button :icon="getIcon('tickets')" class="button-auto-resize" circle @click="getLog"/>
                <el-button :icon="getIcon('refresh')" class="button-auto-resize" type="primary" circle
                           @click="getData"/>
                <el-button :icon="getIcon('plus')" class="button-auto-resize" circle @click="showNewSsl = true"/>
            </el-col>
        </el-row>
        <el-table :data="tabelSslList" border header-cell-class-name="el-table-header-cell" ref="elTableRef"
                  cell-class-name="el-table-cell" highlight-current-row @row-click="rowClick" row-key="CertificateId"
                  :class="`e-page ${showSelection ? 'table-with-pagination' : 'table-without-pagination'}`"
                  @selection-change="selectionChange">
            <el-table-column prop="status" label="" width="30">
                <template #default="scope">
                    <div class="flex-display-center ssl-status">
                        <div :class="getStatusClass(scope.row)"/>
                    </div>
                </template>
            </el-table-column>
            <el-table-column type="selection" width="40" v-if="showSelection"/>
            <el-table-column prop="CertificateId" label="证书ID" min-width="130"/>
            <el-table-column prop="CertSANs" label="绑定域名" min-width="200">
                <template #default="scope">
                    {{ scope.row.CertSANs.join(",") || scope.row.Domain }}
                </template>
            </el-table-column>
            <el-table-column prop="InsertTime" label="申请时间" min-width="190"/>
            <el-table-column prop="CertEndTime" label="过期时间" min-width="190"/>
            <el-table-column prop="StatusName" label="证书状态" width="150">
                <template #default="scope">
                    <el-tag class="input-auto-resize" :type="getTagType(scope.row.Status)" disable-transitions>
                        {{ scope.row.StatusName?.replace("证书", "") }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" fixed="right" :width="operationWidth" className="operation-column">
                <template #default="scope">
                    <el-button type="primary" class="button-auto-resize" link @click="showDetail(scope.row)">
                        查看
                    </el-button>
                    <el-button type="danger" class="button-auto-resize" link @click="revokeCertificate(scope.row)"
                               :disabled="scope.row.Status !== 1" v-if="scope.row.Status !== 0">
                        吊销
                    </el-button>
                    <el-button type="danger" class="button-auto-resize" link @click="deleteCertificate(scope.row)"
                               :disabled="!checkAllowDelete(scope.row)">
                        删除
                    </el-button>
                    <el-button type="success" class="button-auto-resize" link @click="cancelAuditCertificate(scope.row)"
                               v-if="scope.row.Status === 0">
                        取消
                    </el-button>
                    <el-button type="success" class="button-auto-resize" link @click="showDownPage(scope.row)"
                               :disabled="scope.row.Status !== 1" v-if="scope.row.Status !== 0">
                        下载
                    </el-button>
                    <el-button type="success" class="button-auto-resize" link @click="showBatchDeploy(scope.row)"
                               :disabled="scope.row.Status !== 1" v-if="scope.row.Status !== 0">
                        部署
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <div style="height: 50px;">
            <el-button class="fit-auto-resize batch-button" type="warning" :disabled="batchDisabled"
                       @click="batchGetNew" v-if="showSelectionExpire">批量重新申请
            </el-button>
            <el-button class="fit-auto-resize batch-button" type="success" :disabled="batchDisabled"
                       @click="showBatchDeploy()" v-if="showSelectionSign">批量部署
            </el-button>
            <el-button class="fit-auto-resize batch-button" type="warning" :disabled="batchDisabled"
                       @click="showRevokeDrawer = true" v-if="showSelectionSign">批量吊销
            </el-button>
            <el-button class="fit-auto-resize batch-button" type="warning" :disabled="batchDisabled"
                       @click="showRevokeDrawer = true" v-if="showSelectionRevoked">批量删除
            </el-button>
        </div>
        <el-drawer :show-close="false" :with-header="false" size="700px" v-model="showNewSsl" direction="rtl"
                   @open="open" class="forbid-select ssl new-ssl" append-to-body @closed="closeNewSsl"
                   :close-on-click-modal="false">
            <div class="ssl-item">
                <div class="new-ssl-label flex-display-center" checklabel>证书绑定域名</div>
                <div class="new-ssl-content">
                    <el-input v-model="newSsl.domainName" type="textarea" class="font-auto-resize" v-if="newSsl.batch"
                              resize="none" :rows="5" disabled/>
                    <el-input v-model="newSsl.domainName" check="domainName" placeholder="请输入域名"
                              class="input-auto-resize" v-else/>
                </div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label">域名验证方式</div>
                <div class="new-ssl-content">
                    <el-radio-group v-model="newSsl.dvAuthMethod" disabled>
                        <el-radio :value="item" v-for="(item, index) in Object.keys(verifyType)" :key="index">
                            {{ verifyType[item]?.name }}
                        </el-radio>
                    </el-radio-group>
                    <div class="auth-desc">{{ verifyType[newSsl.dvAuthMethod]?.desc }}</div>
                </div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label">自动删除验证</div>
                <div class="new-ssl-content">
                    <el-switch v-model="newSsl.deleteDnsAutoRecord" active-text="开启" inactive-text="关闭"
                               :active-value="true" :inactive-value="false" class=" fit-auto-resize cursor-pointer"
                               inline-prompt :disabled="newSsl.dvAuthMethod !== 'DNS_AUTO' || true"/>
                    <div class="auth-desc">
                        开启后，证书签发成功后系统会自动删除域名验证记录（不影响证书）。自动DNS验证时生效
                    </div>
                </div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label flex-display-center" checklabel>申请邮箱</div>
                <div class="new-ssl-content">
                    <el-input v-model="newSsl.contactEmail" check="mail" placeholder="请输入邮箱"
                              class="input-auto-resize"/>
                </div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label flex-display-center">证书有效期</div>
                <div class="new-ssl-content">90天</div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label">证书算法</div>
                <div class="new-ssl-content">
                    <el-radio-group v-model="newSsl.csrEncryptAlgo" disabled>
                        <el-radio value="RSA">RSA</el-radio>
                        <el-radio value="ECC">ECC</el-radio>
                    </el-radio-group>
                    <div class="auth-desc">
                        RSA对浏览器和客户端的兼容性更好，但对网站服务器的性能开销更大；ECC加密效率更高，服务器性能开销小但兼容性略弱。
                    </div>
                </div>
            </div>
            <div class="ssl-item">
                <div class="new-ssl-label flex-display-center">证书备注名(选填)</div>
                <div class="new-ssl-content">
                    <el-input v-model="newSsl.alias" placeholder="请输入证书备注名，最多100字" maxlength="100"
                              class="input-auto-resize"/>
                </div>
            </div>
            <div class="ssl-item">
                <div class="ssl-button">
                    <div @click="submit" class="cursor-pointer submit" v-ripple>提交</div>
                </div>
                <div class="ssl-button">
                    <div @click="showNewSsl = false" class="cursor-pointer cancel">取消</div>
                </div>
            </div>
        </el-drawer>
        <el-drawer :show-close="false" :with-header="false" size="500px" v-model="showDetailDrawer" direction="rtl"
                   class="forbid-select ssl" append-to-body @open="open" @closed="close">
            <div class="ssl-item">
                <div class="ssl-label">证书ID</div>
                <div class="ssl-content">{{ currentCertificateDetail.CertificateId }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">主域名</div>
                <div class="ssl-content">{{ currentCertificateDetail.Domain }}</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.SubjectAltName.length">
                <div class="ssl-label">所有域名</div>
                <div class="ssl-content">{{ currentCertificateDetail.SubjectAltName?.join(",") }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">申请时间</div>
                <div class="ssl-content">{{ currentCertificateDetail.InsertTime }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">验证方式</div>
                <div class="ssl-content">{{ verifyType[currentCertificateDetail.VerifyType]?.name }}</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.CertBeginTime">
                <div class="ssl-label">生效时间</div>
                <div class="ssl-content">{{ currentCertificateDetail.CertBeginTime }}</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.CertEndTime">
                <div class="ssl-label">到期时间</div>
                <div class="ssl-content">{{ currentCertificateDetail.CertEndTime }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">证书状态</div>
                <div class="ssl-content">{{ currentCertificateDetail.StatusName }}</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.CertFingerprint0">
                <div class="ssl-label">证书指纹</div>
                <div class="ssl-content">{{ currentCertificateDetail.CertFingerprint }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">证书类型</div>
                <div class="ssl-content">{{
                        currentCertificateDetail.CertificateType === "CA" ? "客户端证书" : "服务器证书"
                    }}
                </div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">证书算法</div>
                <div class="ssl-content">{{ currentCertificateDetail.EncryptAlgorithm }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">证书颁发者</div>
                <div class="ssl-content">{{ currentCertificateDetail.ProductZhName }}</div>
            </div>
            <div class="ssl-item">
                <div class="ssl-label">证书有效期</div>
                <div class="ssl-content">{{ currentCertificateDetail.ValidityPeriod }}个月</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.Alias">
                <div class="ssl-label">备注</div>
                <div class="ssl-content">{{ currentCertificateDetail.Alias }}</div>
            </div>
            <div class="ssl-item" v-if="currentCertificateDetail.Status === 9">
                <div class="ssl-label">吊销验证信息</div>
                <div class="ssl-content cursor-pointer" style="color: brown;" @click="getRevokeAuth">
                    查看验证信息
                </div>
            </div>
        </el-drawer>

        <el-dialog title="证书吊销验证信息" v-model="showRevokeAuth" :show-close="false" append-to-body width="1000">
            <el-table :data="revokeCertificateAuth" border header-cell-class-name="el-table-header-cell"
                      cell-class-name="el-table-cell" class="revoke">
                <el-table-column prop="DomainValidateAuthDomain" label="域名" width="200"/>
                <el-table-column prop="DomainValidateAuthKey" label="主机记录" width="300"/>
                <el-table-column prop="AuthType" label="记录类型" width="100">
                    <template #default>
                        CNAME
                    </template>
                </el-table-column>
                <el-table-column prop="DomainValidateAuthValue" label="记录值" width="340"/>
            </el-table>
        </el-dialog>

        <el-drawer :show-close="false" v-model="showLogDrawer" direction="rtl" class="forbid-select log-drawer"
                   append-to-body @open="open" @closed="close" size="1050">
            <template #header>
                只显示近50条操作日志, 更多日志前往腾讯云控制台查看
            </template>
            <el-table :data="logData" border header-cell-class-name="el-table-header-cell"
                      cell-class-name="el-table-cell" class="revoke">
                <el-table-column type="index" width="70"/>
                <el-table-column prop="Uin" label="操作人ID" width="150"/>
                <el-table-column prop="CreatedOn" label="操作时间" width="180"/>
                <el-table-column prop="CertId" label="证书" width="150"/>
                <el-table-column prop="Action" label="事件" min-width="400"/>
            </el-table>
        </el-drawer>

        <el-drawer :show-close="false" v-model="showRevokeDrawer" direction="rtl" class="forbid-select deploy-drawer"
                   append-to-body @open="open" @closed="close" size="900">
            <template #header>
                <div style="padding:10px">{{ sslFilter === 'sign' ? "证书批量吊销确认" : "证书批量删除确认" }}</div>
                <div @click="batchRevoke" class="revoke-button cursor-pointer" v-if="sslFilter === 'sign'">确认吊销
                </div>
                <div @click="batchDelete" class="revoke-button cursor-pointer" v-else>确认删除</div>
            </template>
            <el-table :data="selectionList" border header-cell-class-name="el-table-header-cell"
                      cell-class-name="el-table-cell" class="revoke">
                <el-table-column prop="status" label="" width="50">
                    <template #default="scope">
                        <div class="flex-display-center ssl-status">
                            <div :class="getStatusClass(scope.row)"/>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="CertificateId" label="证书ID" width="130"/>
                <el-table-column prop="CertSANs" label="绑定域名" width="200">
                    <template #default="scope">
                        {{ scope.row.CertSANs.join(",") || scope.row.Domain }}
                    </template>
                </el-table-column>
                <el-table-column prop="InsertTime" label="申请时间" width="180"/>
                <el-table-column prop="CertEndTime" label="过期时间" width="180"/>
                <el-table-column prop="StatusName" label="证书状态" width="150">
                    <template #default="scope">
                        <el-tag class="input-auto-resize" :type="getTagType(scope.row.Status)" disable-transitions>
                            {{ scope.row.StatusName?.replace("证书", "") }}
                        </el-tag>
                    </template>
                </el-table-column>
            </el-table>
        </el-drawer>

        <el-drawer :show-close="false" v-model="showBatchDeployDrawer" direction="rtl" size="940"
                   class="forbid-select deploy-drawer" append-to-body @open="open" @closed="close">
            <template #header>
                <div>
                    <!-- <div style="padding: 5px;">选择服务器部署{{ currentCertificateDetail.Domain }}证书</div> -->
                    <div class="setting-content" v-waterfall="400">
                        <div class="setting-item">
                            <span>部署后移除压缩文件：</span>
                            <span>{{ setting["certificate.zip.remove"] === '0' ? "否" : "是" }}</span>
                        </div>
                        <div class="setting-item">
                            <span>部署后自动重启Nginx：</span>
                            <span>{{ setting["deploy.ssl.auto.reload.nginx"] === '0' ? "否" : "是" }}</span>
                        </div>
                        <div class="setting-item">
                            <span>文件路径：</span>
                            <span>{{ setting["data.dir"] }}</span>
                        </div>
                        <div class="setting-item">
                            <span>Nginx安装路径：</span>
                            <span>{{ setting["nginx.dir"] }}</span>
                        </div>
                    </div>
                </div>
            </template>
            <el-table :data="batchDelpoyCertificateList" border header-cell-class-name="el-table-header-cell"
                      cell-class-name="el-table-cell" class="revoke" highlight-current-row>
                <el-table-column prop="CertSANs" label="绑定域名" width="200">
                    <template #default="scope">
                        {{ scope.row.CertSANs.join(",") || scope.row.Domain }}
                    </template>
                </el-table-column>
                <el-table-column prop="CertEndTime" label="过期时间" width="180"/>
                <el-table-column prop="StatusName" label="证书状态" width="150">
                    <template #default="scope">
                        <el-tag class="input-auto-resize" :type="getTagType(scope.row.Status)" disable-transitions>
                            {{ scope.row.StatusName?.replace("证书", "") }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="instance" label="部署实例" width="250">
                    <template #default="scope">
                        <div @click="setDeployInstance(scope.row)" class="cursor-pointer">
                            <tooltip v-if="scope.row.instance" showTips v-model="scope.row.instanceDesc"/>
                            <div v-else class="underline" style="color: red;">请选择部署实例</div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="deployStatus" label="部署状态" width="150">
                    <template #default="scope">
                        <el-tag class="input-auto-resize" :type="getDeployStatusType(scope.row.deployStatus)"
                                disable-transitions>
                            {{ getDeployStatus(scope.row.deployStatus) }}
                        </el-tag>
                    </template>
                </el-table-column>
            </el-table>
            <template #footer>
                <el-button type="primary" @click="batchDeploy" :disabled="!allowBatchDeploy" class="fit-auto-resize"
                           confirm-title="确实配置信息无误，部署后将直接覆盖原有证书文件">部署
                </el-button>
                <el-button @click="showBatchDeployDrawer = false" class="fit-auto-resize">取消</el-button>
            </template>
        </el-drawer>

        <el-drawer :show-close="false" v-model="showDeployInstanceDrawer" direction="rtl" append-to-body
                   class="forbid-select deploy-drawer deploy-instance" size="450">
            <template #header>
                <div>选择服务器部署{{ currentCertificateDetail.Domain }}证书</div>
            </template>
            <div class="instance-list">
                <div v-for="(item, index) in instanceInfo" :key="index" @click="setBatchDeployInstance(item)"
                     :class="`instance-content cursor-pointer ${currentCertificateDetail.instance?.InstanceId === item.InstanceId ? 'active' : ''}`">
                    <div class="instance-item">
                        <span class="instance-label">实例ID：</span>
                        <span class="instance-value">{{ item.InstanceId }}</span>
                    </div>
                    <div class="instance-item">
                        <span class="instance-label">实例名称：</span>
                        <span class="instance-value">{{ item.InstanceName }}</span>
                    </div>

                    <div class="instance-item">
                        <span class="instance-label">Ip地址：</span>
                        <span class="instance-value">{{ item.PrivateAddresses?.join(",") }}(内)</span>
                        <span class="instance-value">{{ item.PublicAddresses?.join(",") }}(外)</span>
                    </div>
                </div>
            </div>
        </el-drawer>
    </div>
</template>

<script setup>
import {
    useSetTableOperationWidth,
    useModalSize,
    useRequest,
    useElMessage,
    useElLoading,
    useElMessageBox,
    useDataCheck
} from "@usehook"
import {onMounted} from "vue"
import {getIcon, getLastDomain} from "@/utils/tools"
import {baseUrl} from "@/utils/constant"

const operationWidth = useSetTableOperationWidth(5)
const {check} = useDataCheck({"domainName": "域名不能为空", "mail": "邮箱不能为空"})
let sslList = $ref([])
let loading = $ref(false)
let showDetailDrawer = $ref(false)
let currentCertificateDetail = $ref({})
let showNewSsl = $ref(false)
let newSsl = $ref({
    dvAuthMethod: "DNS_AUTO",
    domainName: "",
    csrEncryptAlgo: "RSA",
    oldCertificateId: "",
    contactEmail: "",
    deleteDnsAutoRecord: true,
    alias: "",
    batch: false
})
let sslFilter = $ref("total")
let showSelectionExpire = $computed(() => sslFilter === 'isExpiring' || sslFilter === 'expired')
let showSelectionSign = $computed(() => sslFilter === 'sign')
let showSelectionRevoked = $computed(() => sslFilter === 'revoked')
let showSelection = $computed(() => showSelectionExpire || showSelectionSign || showSelectionRevoked)
const elTableRef = ref(null)
let selectionList = $ref([])
let showRevokeDrawer = $ref(false)
let showRevokeAuth = $ref(false)
let revokeCertificateAuth = $ref([])
let logData = $ref([])
let showLogDrawer = $ref(false)
let showBatchDeployDrawer = $ref(false)
let showDeployInstanceDrawer = $ref(false)
let batchDelpoyCertificateList = $ref([])
let instanceInfo = $ref([])
let setting = $ref({})

const allowBatchDeploy = $computed(() => {
    return batchDelpoyCertificateList.filter(e => e.instance?.InstanceId).length === batchDelpoyCertificateList.length
})

const getRevokeAuth = () => {
    const useloading = useElLoading({text: "正在查询吊销验证信息"})
    useRequest("/tencentCloud/revokeCertificateAuth", {certificateId: currentCertificateDetail.CertificateId}).then(resp => {
        if (resp && resp.status) {
            revokeCertificateAuth = resp.data.RevokeDomainValidateAuths
            showRevokeAuth = true
        }
    }).finally(_ => {
        useloading.close()
    })
}

const showBatchDeploy = async (row) => {
    const useloading = useElLoading({text: "正在获取相关配置信息"})
    try {
        batchDelpoyCertificateList = (row ? [row] : selectionList).map(e => {
            return {
                CertificateId: e.CertificateId,
                Status: e.Status,
                IsExpiring: e.IsExpiring,
                CertSANs: e.CertSANs,
                Domain: e.Domain,
                InsertTime: e.InsertTime,
                CertEndTime: e.CertEndTime,
                StatusName: e.StatusName,
                accessInstance: e.accessInstance
            }
        })

        const domain = getLastDomain(batchDelpoyCertificateList[0]?.Domain)
        const accessInstance = getLastDomain(batchDelpoyCertificateList[0]?.accessInstance)
        const resp = await useRequest("/tencentCloud/describeRecordList", {domain, instance: accessInstance})

        const domainMap = resp && resp.status ? resp.data.RecordList.filter(e => e.Type === "A").map(e => {
            return {name: e.Name === "@" ? domain : e.Name + "." + domain, value: e.Value}
        }).reduce((acc, item) => {
            acc[item.name] = item.value
            return acc
        }, {}) : []
        await getInstance()
        getSetting()
        if (instanceInfo && instanceInfo.length) {
            for (let certificate of batchDelpoyCertificateList) {
                const instance = instanceInfo.filter(e => e.PublicAddresses[0] === domainMap[certificate.Domain])[0]
                if (!instance || Object.keys(instance).length === 0) continue
                certificate.instance = {
                    PublicAddresses: instance.PublicAddresses,
                    InstanceId: instance.InstanceId,
                    PrivateAddresses: instance.PrivateAddresses,
                    InstanceName: instance.InstanceName
                }
                certificate.instanceDesc = `实例名称：${instance.InstanceName},实例ID：${instance.InstanceId}, 公网IP：${instance.PublicAddresses}, 内网IP：${instance.PrivateAddresses}`
            }
        }
        showBatchDeployDrawer = true
    } catch (e) {
        useElMessage.error("获取配置信息失败")
    } finally {
        useloading.close()
    }
}

// 打开实例列表弹窗
const setDeployInstance = (row) => {
    showDeployInstanceDrawer = true
    currentCertificateDetail = row
}

// 转换部署状态
const getDeployStatus = (status) => {
    switch (status) {
        case null:
        case undefined:
            return "等待部署"
        case 0:
            return '部署失败'
        case 1:
            return '部署成功'
        case 2:
            return '正在部署'
        default:
            return "状态未知:" + status
    }
}

// 转换部署状态tag
const getDeployStatusType = (status) => {
    switch (status) {
        case null:
        case undefined:
            return "info"
        case 0:
            return 'danger'
        case 1:
            return 'success'
        case 2:
            return 'warning'
        default:
            return "primary"
    }
}

// 实例列表弹窗，批量部署证书选择服务器
const setBatchDeployInstance = (instance) => {
    currentCertificateDetail.instance = {
        PublicAddresses: instance.PublicAddresses,
        InstanceId: instance.InstanceId,
        PrivateAddresses: instance.PrivateAddresses,
        InstanceName: instance.InstanceName
    }
    currentCertificateDetail.instanceDesc = `实例名称：${instance.InstanceName},实例ID：${instance.InstanceId}, 公网IP：${instance.PublicAddresses}, 内网IP：${instance.PrivateAddresses}`
    showDeployInstanceDrawer = false
}

//deployStatus 初始值null   1 成功 0 失败 2 正在部署
const batchDeploy = () => {
    const useloading = useElLoading({text: "正在部署证书, 请勿刷新页面"})
    let doEnd = 0

    for (let c of batchDelpoyCertificateList) {
        c.deployStatus = 2
        useRequest.post("/tencentCloud/deployCertificate", {
            certificateId: c.CertificateId,
            instance: c.accessInstance,
            instanceId: c.instance.InstanceId
        }).then(resp => {
            if (resp && resp.status) {
                useElMessage.success("证书部署成功")
                c.deployStatus = 1
            } else {
                c.deployStatus = 0
            }
        }).catch(() => {
            c.deployStatus = 0
        }).finally(() => {
            doEnd += 1
            if (doEnd === batchDelpoyCertificateList.length) {
                useloading.close()
            }
        })
    }
}

// 行点击事件，修改选中状态
const rowClick = (row) => {
    if (!showSelection) return
    elTableRef.value.toggleRowSelection(row)
}

// 选中行变化事件
const selectionChange = selection => {
    selectionList = selection
}

// 批量按钮是否禁用
const batchDisabled = computed(() => !selectionList.length)

// 批量创建新的域名证书
const batchGetNew = () => {
    showNewSsl = true
    newSsl.domainName = selectionList.map(e => e.Domain).join("\n")
    newSsl.batch = true
}

// 批量吊销域名证书
const batchRevoke = () => {
    useElMessageBox("吊销证书提示", "确认批量吊销选中的" + selectionList.length + "张证书?", {
        type: "warning",
        showCancelButton: true,
        showConfirmButton: true,
    }).then(() => {
        const useloading = useElLoading({text: "证书批量吊销请求正在发送中"})
        useRequest.post("/tencentCloud/revokeCertificate", {
            certificateId: selectionList.map(e => e.CertificateId).join(","),
            instance: selectionList.map(e => e.accessInstance)[0],
            batch: true
        }).then(resp => {
            if (resp && resp.status) {
                useElMessage.success(resp.message)
                getData()
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

// 批量删除域名证书
const batchDelete = () => {
    useElMessageBox("删除证书提示", "确认批量删除选中的" + selectionList.length + "张证书?", {
        showCancelButton: true,
        showConfirmButton: true,
        type: "warning"
    }).then(() => {
        const useloading = useElLoading({text: "证书批量删除请求正在发送中"})
        useRequest.post("/tencentCloud/deleteCertificate", {
            certificateId: selectionList.map(e => e.CertificateId).join(","),
            instance: selectionList.map(e => e.accessInstance)[0],
            batch: true
        }).then(resp => {
            if (resp && resp.status) {
                useElMessage.success(resp.message)
                getData()
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

// 各种状态值汇总
const sslSummary = computed(() => ({
    total: sslList.length,
    expired: sslList.filter(e => e.Status === 3).length,
    expiring: sslList.filter(e => e.IsExpiring).length,
    review: sslList.filter(e => e.Status === 0).length,
    sign: sslList.filter(e => e.Status === 1).length,
    isExpiring: sslList.filter(e => e.IsExpiring).length,
    revoked: sslList.filter(e => e.Status === 10).length,
}))

// 调整当前显示标签
const setFilter = (type) => {
    if (type === 'total' || (sslSummary.value[type] && sslSummary.value[type] !== sslSummary.value['total']) || type === 'sign' || type === 'isExpiring') {
        sslFilter = type
    }
}

//获取证书数据
const getData = () => {
    loading = true
    useRequest("/tencentCloud/describeCertificates").then(resp => {
        if (resp && resp.status) {
            sslList = resp.data.reduce((acc, curr) => {
                // 将当前对象的Certificates数组添加到累加器数组中
                return acc.concat(curr.Certificates.map(e => ({...e, accessInstance: curr.instance})));
            }, []) // 初始累加器数组为空数组
        }
    }).finally(_ => {
        loading = false
    })
}

// 获取腾讯云控制台操作日志
const getLog = () => {
    const useloading = useElLoading({text: "正在获取操作日志数据"})
    useRequest("/tencentCloud/describeCertificateOperateLogs").then(resp => {
        if (resp && resp.status) {
            logData = resp.data
            showLogDrawer = true
        } else {
            useElMessage.error(resp.message === "PageNotFound" ? "接口地址不存在，日志获取失败" : "日志获取失败")
        }
    }).catch((resp) => {
        useElMessage.error(resp.message === "PageNotFound" ? "接口地址不存在，日志获取失败" : "日志获取失败")
    }).finally(_ => {
        useloading.close()
    })
}

// 获取标签class，设置选中状态
const getFilterButtonClass = (type) => {
    const pointerClass = type === 'total' || (sslSummary.value[type] && sslSummary.value[type] !== sslSummary.value['total']) ? 'cursor-pointer' : ''
    return `desc-item ${pointerClass} ${sslFilter === type ? 'select' : ''}`
}

// 计算标签点击后表格数据
const tabelSslList = computed(() => {
    return sslList.filter(e => {
        if (sslFilter === 'total') return true
        if (sslFilter === 'expired') return e.Status === 3
        if (sslFilter === 'review') return e.Status === 0
        if (sslFilter === 'sign') return e.Status === 1
        if (sslFilter === 'isExpiring') return e.IsExpiring
        if (sslFilter === 'revoked') return e.Status === 10
    })
})

// 验证类型列表
const verifyType = {
    DNS: {name: "手动DNS验证", desc: "手动前往域名解析平台添加一条解析记录（不影响域名使用），证书签发成功后即可删除记录"},
    DNS_AUTO: {
        name: "自动DNS验证",
        desc: "您的域名解析在腾讯云，可以使用自动添加DNS验证域名，无需手动添加域名解析记录，验证较快。"
    },
    FILE: {
        name: "文件验证",
        desc: "您的域名必须要解析到服务器，域名验证时，需要在网站根目录下创建指定的文件，操作复杂，验证速度较慢"
    }
}

const close = () => {
    useModalSize(false)
}

const open = () => {
    useModalSize()
}

const {loading: instanceloading, close: instanceClose} = useElLoading({
    text: "正在加载服务器资源信息",
    target: ".instance-list",
    manual: true
})

// 获取部署配置信息
const getSetting = () => {
    useRequest("/tencentCloud/getSetting").then(resp => {
        if (resp && resp.status) {
            setting = resp.data
        }
    }).catch((error) => {
        if (error.message) useElMessage.error(error.message)
    }).finally(_ => {
    })
}

// 获取服务器实例信息
const getInstance = () => {
    return new Promise(resolve => {
        if (instanceInfo.length) {
            resolve(true)
        } else {
            instanceloading()
            useRequest("/tencentCloud/describeInstance").then(resp => {
                if (resp && resp.status) {
                    instanceInfo = resp.data.reduce((acc, curr) => {
                        // 将当前对象的Certificates数组添加到累加器数组中
                        return acc.concat(curr.InstanceSet.map(e => ({...e, accessInstance: curr.instance})));
                    }, [])
                }
            }).catch((error) => {
                if (error.message) useElMessage.error("获取服务器实例信息失败")
            }).finally(_ => {
                instanceClose()
                resolve(true)
            })
        }
    })
}

// 获取状态类
const getStatusClass = (row) => {
    if (row.Status === 1 && row.IsExpiring) {
        return "ssl-warning"
    } else if (row.Status !== 1) {
        return "ssl-disable"
    } else {
        return "ssl-enable"
    }
}

// 监听dvAuthMethod
watch(() => newSsl.dvAuthMethod, method => {
    if (method !== "DNS_AUTO") newSsl.deleteDnsAutoRecord = false
})

const closeNewSsl = () => {
    newSsl = {
        dvAuthMethod: "DNS_AUTO",
        domainName: "",
        csrEncryptAlgo: "RSA",
        oldCertificateId: "",
        contactEmail: "",
        deleteDnsAutoRecord: true,
        alias: "",
        batch: false
    }
    close()
}

// 单个证书申请提交
const submit = () => {
    check().then(() => {
        const useloading = useElLoading({text: "正在提交申请"})
        useRequest.post("/tencentCloud/createCertificate", {...newSsl, instance: "dansj.cn"}).then((resp) => {
            if (resp && resp.status) {
                if (newSsl.batch) {
                    useElMessage.success(resp.message)
                } else if (resp.data.CertificateId && resp.data.RequestId) {
                    useElMessage.success("证书申请提交成功,正在审核中")
                    getData()
                }
                showNewSsl = false
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

// 查看证书详情
const showDetail = (row) => {
    loading = true
    useRequest("/tencentCloud/describeCertificateDetail", {
        certificateId: row.CertificateId,
        instance: row.accessInstance
    }).then(resp => {
        if (resp && resp.status) {
            currentCertificateDetail = resp.data
            showDetailDrawer = true
        }
    }).finally(_ => {
        loading = false
    })
}

const getTagType = (status) => {
    return status === 1 ? "success" : status == 0 ? "primary" : status === 9 ? "warning" : "danger"
}

const map = {
    "TOMCAT": "Tomcat（pfx格式）",
    "JKS": "Tomcat（JKS格式）",
    "APACHE": "Apache（crt文件、key文件）",
    "NGINX": "Nginx（适用大部分场景）（pem文件、crt文件、key文件）",
    "IIS": "IIS（pfx文件）",
    "OTHER": "其他（pem文件、crt文件、key文件）",
    "ROOT": "根证书下载（crt文件）"
}

const showDownPage = (row) => {
    const list = Object.keys(row.SupportDownloadType).filter(e => row.SupportDownloadType[e])
        .map(e => {
            return h("div", {class: "oneline"}, [h("div", {class: "desc"}, map[e]), h("div", {
                class: "download-button cursor-pointer", onclick: () => {
                    const useloading = useElLoading({text: "正在准备下载证书"})
                    useRequest("/tencentCloud/describeDownloadCertificateUrl", {
                        instance: row.accessInstance,
                        serviceType: e.toLowerCase(),
                        certificateId: row.CertificateId
                    }).then(resp => {
                        if (resp && resp.status) {
                            let link = document.createElement('a')
                            link.href = baseUrl + "/tencentCloud/downloadCertificate/" + resp.data
                            link.click()
                            nextTick(() => link.remove())
                        }
                    }).finally(() => useloading.close())
                }
            }, "下载")])
        })
    useElMessageBox("下载证书[" + row.Domain + "]", () => h("div", {}, list), {
        showIcon: false,
        showConfirmButton: false,
        closeOnClickModal: true,
        customClass: "download"
    })
}

const checkAllowDelete = (row) => {
    return !([1, 6, 8, 9, 11].includes(row.Status))
}
const deleteCertificate = (row) => {
    const showConfirmButton = checkAllowDelete(row)
    const message = showConfirmButton ? "证书删除后，列表中将无法看到该条证书记录。" : "当前证书还在有效期内，无法直接删除</br>如证书不再使用，可先申请吊销，吊销成功后再删除证书。"
    useElMessageBox("删除证书提示", message, {
        showCancelButton: true,
        showConfirmButton,
        type: "warning"
    }).then(() => {
        const useloading = useElLoading({text: "证书正在删除"})
        useRequest.post("/tencentCloud/deleteCertificate", {
            certificateId: row.CertificateId,
            instance: row.accessInstance
        }).then(resp => {
            if (resp && resp.status && resp.data.DeleteResult && resp.data.RequestId) {
                useElMessage.success("删除成功")
                getData()
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

const cancelAuditCertificate = (row) => {
    useElMessageBox("删除证书提示", `确认取消${row.Domain}证书的申请审核?`, {
        showCancelButton: true,
        showConfirmButton: true,
        type: "warning"
    }).then(() => {
        const useloading = useElLoading({text: "正在取消证书申请"})
        useRequest.post("/tencentCloud/cancelAuditCertificate", {
            certificateId: row.CertificateId,
            instance: row.accessInstance
        }).then(resp => {
            if (resp && resp.status && resp.data.Result && resp.data.RequestId) {
                useElMessage.success("申请取消成功")
                getData()
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

const revokeCertificate = (row) => {
    const message = row.CertificateExtra.ReplacedFor ? `重颁发证书只需吊销原证书即可，原证书ID：${row.CertificateExtra.ReplacedFor}` : row.Status !== 1 ? "当前状态不可以吊销证书" : ""
    const normalMessage = row.CertificateExtra.ReplacedBy ? `当前证书已重颁发为 <span class='red-color'>${row.CertificateExtra.ReplacedBy}</span></br>吊销当前证书也会将重颁发后的证书 <span class='red-color'>${row.CertificateExtra.ReplacedBy}</span> 一并吊销</br>请确定是否继续吊销此证书?` : "确定吊销此证书?"
    useElMessageBox("吊销证书提示", message ? message : normalMessage, {
        type: "warning",
        showCancelButton: true,
        showConfirmButton: !message,
    }).then(() => {
        const useloading = useElLoading({text: "证书吊销请求正在发送中"})
        useRequest.post("/tencentCloud/revokeCertificate", {
            certificateId: row.CertificateId,
            instance: row.accessInstance
        }).then(resp => {
            if (resp && resp.status && resp.data.RequestId && resp.data.RevokeDomainValidateAuths.length) {
                useElMessage.success("吊销请求成功，证书正在吊销中\n需要撤销请求请从控制台查看删除对应的解析记录")
                getData()
                console.log("删除以下的解析记录，或者前往控制台取消吊销证书")
                console.table(resp.data.RevokeDomainValidateAuths)
            }
        }).finally(_ => {
            useloading.close()
        })
    })
}

onMounted(() => {
    getData()
})
</script>

<style>
.ssl .ssl-item {
    display: flex;
    padding-top: 20px;
}

.ssl .ssl-label {
    padding-right: 15px;
    width: 110px;
    text-align: right;
}

.ssl .ssl-content {
    width: calc(100% - 140px);
}

.ssl .new-ssl-label {
    padding-right: 15px;
    width: calc(var(--font-size) * 10);
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.ssl .new-ssl-content {
    width: calc(100% - var(--font-size) * 13);
    position: relative;
}

.ssl .auth-desc {
    font-size: calc(var(--font-size) - 4px);
    color: #c18b0c;
}

.ssl .ssl-button {
    width: 50%;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ssl .ssl-button .submit {
    background: #b7d7ff;
    padding: 10px 20px;
    border-radius: 3px;
}

.ssl .ssl-button .cancel {
    background: #dddddd;
    padding: 10px 20px;
    border-radius: 3px;
}

.ssl-enable {
    background: green;
    width: 15px;
    height: 15px;
    border-radius: 50%;
}

.ssl-disable {
    background: red;
    width: 15px;
    height: 15px;
    border-radius: 50%;
}

.ssl-warning {
    background: orange;
    width: 15px;
    height: 15px;
    border-radius: 50%;
}

.ssl .el-table__cell .cell:has(.ssl-status) {
    padding: 0;
}

.use-el-message-box .oneline {
    height: 50px;
    display: flex;
    align-items: center;
    padding: 0 10px;
}

.use-el-message-box .oneline:hover {
    background: #dddddd;

    border-radius: 3px
}

.use-el-message-box .desc {
    width: 500px;
}

.use-el-message-box.download {
    top: 18vh
}

.use-el-message-box .download-button {
    padding: 5px;
}

.use-el-message-box .download-button:hover {
    border-radius: 3px;
    color: green;
}

.ssl .total-desc {
    display: flex;
    height: 100%;
    align-items: center;
    margin-left: 10px;
}

.ssl .desc-item {
    padding: 5px 10px;
}

.ssl .desc-item + .desc-item {
    margin-left: 30px;
}

.ssl .desc-item.select {
    background: #4cabff;
    border-radius: 3px;

    color: #ffffff;
}

.deploy-drawer .instance-content {
    padding: 5px;
    background: rgb(169 169 169 / 38%);
    border-radius: 3px;
    transition: background .3s;
}

.deploy-drawer .instance-content + .instance-content {
    margin-top: 5px;
}

.deploy-drawer .instance-value + .instance-value {
    padding-left: 5px;
}

.deploy-drawer .instance-label {
    padding-right: 5px;
    width: calc(var(--font-size) * 5 + 10px);
    display: inline-block;
    text-align: right;
}

.deploy-drawer .instance-item {
    padding: 5px;
}

.deploy-drawer .instance-content.active {
    background: #badfff;
}

.deploy-drawer .instance-list {
    height: 100%;
}

.deploy-drawer .deploy-title {
    padding-bottom: 10px;
}

.deploy-drawer .setting-content {
    background: fixed rgb(255 217 89 / 10%);
    padding: 5px 10px;
    border-radius: 3px;
    margin-top: 5px;
}

.deploy-drawer .setting-item + .setting-item {
    padding-top: 5px;
}

.deploy-drawer .el-drawer__header {
    padding: 5px 10px 0 10px;
}

.deploy-drawer .el-drawer__footer {
    padding: 10px;
}

.ssl .el-checkbox__input.is-disabled .el-checkbox__inner {
    background-color: rgb(193 193 193);
    border-color: rgb(99 99 99 / 10%);
}

.ssl .batch-button {
    margin: 9px;
}

.revoke {
    height: 100%;
}

.revoke-button {
    background: #b7d7ff;
    padding: 7px;
    border-radius: 3px;
}

.revoke-button:hover {
    color: #ffffff;
}

.deploy-instance .el-drawer__header {
    padding: 10px;
}
</style>